home *** CD-ROM | disk | FTP | other *** search
- /*
- copyright © 1992-1996 Apple Computer Inc. All rights reserved.
-
- OldApp.c
- This file implements old application message overrides for the specific driver.
-
- Included in this file is the old PrintRecord emulation. Note that the ImageWriter
- PrintRecord is a wonder of misdirection and special cases. You'll have fun
- figuring out the code - so unless you really want to exactly emulate the ImageWriter
- pages, you shouldn't spend too much time looking at this code.
-
- Modification history
- 7/23/92 TED New file today
- 12/20/93 dmh Sync'd with the shipping 1.0b3 GX driver.
- 12/22/93 dmh Added custom dialog code.
- 12/09/94 dmh Corrected illegal use of lUser
- PrDialogRec fields, and corrected
- disposal of gloabal data. This resulted
- in removal of gxStlDialog override and
- the addition of a gxPrDlgMain override.
- 12/10/94 dmh HandleJobDlogItems wasn't sending
- "Print" hits to the GX itemProc, so
- dctl settings weren't being saved.
- Fixed.
- 6/14/96 cn Updated to support Universal Interfaces 2.1.
- */
-
- #include <Errors.h>
- #include <ToolUtils.h>
- #include <StdIO.h>
- #include <StdLib.h>
- #include <String.h>
- #include <Strings.h>
- #include <Resources.h>
- #include <ToolUtils.h>
- #include <OSUtils.h>
- #include <Files.h>
- // #include <SysEqu.h>
- #include <Types.h>
- #include <Packages.h>
- #include <Memory.h>
- #include <Serial.h>
- #include <Devices.h>
- #include <Fonts.h>
- #include <Printing.h>
- #include <Script.h>
- #include <Events.h>
- #include <Dialogs.h>
- #include <FixMath.h>
- #include <Lists.h>
- #include <AppleTalk.h>
- #include <Menus.h>
- #include <Events.h>
- #include <Balloons.h>
- #include <Folders.h>
-
- // Include the new QuickDraw GX graphics header files
- #include <GXGraphics.h>
- #include <GraphicsLibraries.h>
- #include <GXMath.h>
- #include <QDLibrary.h>
- #include <FontLibrary.h>
- #include <GXLayout.h>
-
- // Include the required Printing Manager header files
- #include <GXPrinting.h>
- #include <GXPrinterDrivers.h>
- #include <Collections.h>
- #include <GXMessages.h>
- #include <PrintingLibraries.h>
-
- #include <GXExceptions.h>
-
- #include "CommonDefines.h" // Things common to .r and .h files
-
-
- // Routines to save and retrieve our jump table globals. These
- // routines are in OldApp.a
-
- extern void SetDialogGlobals(DialogGlobalsHdl theGlobals);
- extern DialogGlobalsHdl GetDialogGlobals(void);
-
- /* ---------------------------------------------------------------------------- */
- /* INTERNAL TYPEDEFS AND STRUCTURES */
- /* ---------------------------------------------------------------------------- */
- /* ---------------------------------------------------------------------------- */
-
- // ImageWriter wDev values
- #define kBest 0x01
- #define kPortrait 0x02
- #define kTallAdjusted 0x04
- #define k50Percent 0x08
- #define kNoGaps 0x10
- #define kSetResCalled 0x20
-
- // some ImageWriter constants
- #define kGapSize 60 // gap at top of page in 120ths of an inch
- #define kSmallPlaten 16 // platen width in half inches for small IW
- #define kBigPlaten 27 // platen width in half inches for the 15" IW
-
-
- // Prototypes:
-
- OSErr UpdatePrintRecord(THPrint hPrint);
- OSErr SD_ConvertPrintRecordTo(THPrint hoPrint);
- OSErr SD_ConvertPrintRecordFrom(gxUniversalPrintRecordHdl huPrint);
- OSErr SD_PrintRecordToJob(THPrint hPrint, gxJob theJob);
- OSErr SD_PrValidate(THPrint hPrint, Boolean *wasChanged);
-
- OSErr CreateAndStoreGlobals(DialogGlobalsHdl *dlogGlobals);
- void DisposeGlobals(void);
-
- OSErr SD_PrDlgMain(THPrint hPrint, PDlgInitProcPtr initProc,
- Boolean *userConfirmed);
-
- OSErr SD_PrJobInit(THPrint hPrint, TPPrDlg *pDlg);
- OSErr InitJobDlogData(TPPrDlg pDlg);
- pascal void HandleJobDlogItems(TPPrDlg pDlg, short itemNo);
- OSErr SD_PrStlDialog(THPrint hPrint, Boolean *userConfirmed);
- OSErr SD_PrStlInit(THPrint hPrint, TPPrDlg *pDlg);
-
- OSErr InitStlDlogData(TPPrDlg pDlg);
- pascal void HandleStlDlogItems(TPPrDlg pDlg, short itemNo);
-
- void DoOptionsDialog();
- pascal Boolean OptionsDlogFilterProc(DialogPtr theDialog, EventRecord *theEvent,
- short *itemHit);
- void HandleOptionsDlogItems(short itemNo);
-
- void ToggleControl(void **itemH);
- void DrawFlippedPict(void);
- void SetCurFlip(DialogPtr theDialog, char curFlipping);
-
- // --------------- start of the good stuff ------------
-
-
- /* ---------------------------------------------------------------------------- */
- /* INTERNAL ROUTINES */
- /* ---------------------------------------------------------------------------- */
-
- OSErr UpdatePrintRecord(THPrint hPrint)
- {
- OSErr anErr;
- gxUniversalPrintRecordHdl huPrint = (gxUniversalPrintRecordHdl) hPrint;
- gxUniversalPrintRecordPtr puPrint;
- short devVRes, devHRes, appVRes, appHRes;
- short cPlaten;
-
- // convert to universal format
- anErr = SD_ConvertPrintRecordTo(hPrint);
- if (anErr == noErr)
- {
- // determine application & device resolutions, based upon quality mode, tall adjusted
- // setting, and if the app called SetRsl:
- // draft - 80(h)*72(v)
- // faster - 80(h)*72(v)
- // best - 160(h)*144(v)
- //
- // draft (tall adjusted) - 72*72
- // faster (tall adjusted) - 72*72
- // best (tall adjusted) - 144*144
-
- puPrint = *huPrint;
- if (puPrint->options & gxPreciseBitmap)
- switch(puPrint->qualityMode)
- {
- case gxDraftQuality:
- case gxFasterQuality:
- devVRes = devHRes = 72;
- appVRes = appHRes = 72;
- break;
-
- case gxBestQuality:
- devVRes = devHRes = 144;
- appVRes = appHRes = 72;
- break;
- }
- else
- switch(puPrint->qualityMode)
- {
- case gxDraftQuality:
- case gxFasterQuality:
- appVRes = devVRes = 72;
- appHRes = devHRes = 80;
- break;
-
- case gxBestQuality:
- devVRes = 144;
- devHRes = 160;
- appVRes = 72;
- appHRes = 80;
- break;
- }
-
- // SetRsl was called? Use the resolution specified by the application
- if (puPrint->appVRes != 72)
- {
- appVRes = devVRes = puPrint->appVRes;
- appHRes = devHRes = puPrint->appHRes;
- }
-
- // finally, store the app & device resolutions
- puPrint->devVRes = devVRes;
- puPrint->devHRes = devHRes;
- puPrint->appVRes = appVRes;
- puPrint->appHRes = appHRes;
-
- // here we do page size calculations
- // Please note that this code is confusing - it's purpose is to emulate
- // the existing ImageWriter driver's page size. Most drivers would not
- // do this - the existing in the system probably is good enough.
- {
- long pageGap; // gap at top of page
- long dvPaper, dhPaper; // paper size at device res
- long dvPage, dhPage; // page size at device res
- long scanLines, scanBits; // # of scan lines or bits on page
- long maxH; // maximum width
- long hOff, vOff; // margins (horiz & vert) to get paper rect from page rect
-
- // gap at the top of the page in pixels
- pageGap = (kGapSize * appVRes) / 120;
- if (puPrint->options & gxBiggerPages)
- pageGap = 0;
-
- // figure out paper size in application space pixels
- dvPaper = (puPrint->pageV * appVRes) / 120;
- dhPaper = (puPrint->pageH * appHRes) / 120;
-
- // vertically, align to the head height of 8 pixels
- scanLines = ((dvPaper - pageGap) >> 3) << 3;
-
- // horizontally, allow the biggest width we can handle
- cPlaten = kSmallPlaten;
- if (puPrint->pageH > (9*120) )
- cPlaten = kBigPlaten;
-
- maxH = (cPlaten * appHRes) >> 1;
- if (maxH > dhPaper)
- maxH = dhPaper;
- scanBits = (maxH >> 4) << 4;
-
- if (puPrint->orientation == gxPortraitOrientation)
- {
- // portrait
-
- dhPage = scanBits;
- dvPage = scanLines;
-
- hOff = (dhPage - dhPaper) >> 1;
- vOff = -pageGap;
- }
- else
- {
- // landscape
-
- dhPage = scanLines;
- dvPage = scanBits;
-
- // reverse the paper definition as well
- {
- long iTemp = dhPaper;
- dhPaper = dvPaper;
- dvPaper = iTemp;
- }
-
- hOff = -pageGap;
- vOff = (dvPage - dvPaper) >> 1;
- }
-
- // 50% reduction? scale everything by 2X
- if (puPrint->options & gxUserFlag0)
- {
- dhPage <<= 1;
- dvPage <<= 1;
- dhPaper <<= 1;
- dvPaper <<= 1;
- hOff <<= 1;
- vOff <<= 1;
- }
-
- // set the page and paper in app space
- puPrint->appPage.left = puPrint->appPage.top = 0;
- puPrint->appPage.right = dhPage;
- puPrint->appPage.bottom = dvPage;
-
- puPrint->appPaper.left = hOff;
- puPrint->appPaper.top = vOff;
- puPrint->appPaper.right = dhPaper + hOff;
- puPrint->appPaper.bottom = dvPaper + vOff;
-
- // from page, scale up to device space (in case some weenie decides to look at that)
- puPrint->devPage.left = puPrint->devPage.top = 0;
- puPrint->devPage.right = dhPage * devHRes / appHRes;
- puPrint->devPage.bottom = dvPage * devVRes / appVRes;
- }
-
- // convert back to non-universal format
- anErr = SD_ConvertPrintRecordFrom((gxUniversalPrintRecordHdl) hPrint);
- }
-
- return(anErr);
-
- } // UpdatePrintRecord
-
- //<FF>
- /* ---------------------------------------------------------------------------- */
- /* MESSAGE OVERRIDES */
- /* ---------------------------------------------------------------------------- */
- OSErr SD_ConvertPrintRecordTo(THPrint hoPrint)
- /*
- This call takes a print record in old style (driver specific) format, and
- converts it to the format of "gxUniversalPrintRecordHdl"
- */
- {
- TPPrint poPrint; // pointer to old style print record
- gxUniversalPrintRecordHdl huPrint = (gxUniversalPrintRecordHdl) hoPrint; // handle to universal print record
- gxUniversalPrintRecordPtr puPrint; // pointer to universal print record
- short qualityMode; // cached quality mode
- short wDev; // cached wDev
-
- // cache pointers for size and speed
- puPrint = *huPrint;
- poPrint = *hoPrint;
- wDev = poPrint->prStl.wDev;
-
- // determine quality mode
- if (poPrint->prJob.bJDocLoop == 0)
- qualityMode = gxDraftQuality;
- else
- {
- if (wDev & kBest)
- qualityMode = gxBestQuality;
- else
- qualityMode = gxFasterQuality;
- }
-
- // universal feed is the inverse of our feed
- puPrint->feed = 1-(poPrint->prStl.feed);
-
- // wDev 0x02 means portrait, else landscape
- if (wDev & kPortrait)
- puPrint->orientation = gxPortraitOrientation;
- else
- {
- puPrint->orientation = gxLandscapeOrientation;
-
- // landscape disabled draft, forces tall adjusted
- if (qualityMode == gxDraftQuality)
- qualityMode = gxFasterQuality;
- wDev |= kTallAdjusted;
- }
-
- // copies are in iCopies field (wow.)
- puPrint->actualCopies = poPrint->prJob.iCopies;
-
- // store our flags
- puPrint->options = 0;
-
- // tall adjusted
- if (wDev & kTallAdjusted)
- puPrint->options |= gxPreciseBitmap;
-
- // 50% reduction
- if (wDev & k50Percent)
- {
- puPrint->options |= gxUserFlag0;
- puPrint->reduction = 50;
-
- // for 50% reduction, we always return faster to the application
- qualityMode = gxFasterQuality;
- }
- else
- puPrint->reduction = 100;
-
- // no gaps
- if (wDev & kNoGaps)
- puPrint->options |= gxBiggerPages;
-
- // finally, store quality mode
- puPrint->qualityMode = qualityMode;
-
- // and we can't have any errors - because this code is too godlike.
- return(noErr);
-
- } // SD_ConvertPrintRecordTo
-
- //<FF>
- /* ---------------------------------------------------------------------------- */
- OSErr SD_ConvertPrintRecordFrom(gxUniversalPrintRecordHdl huPrint)
- /*
- This call takes a print record in universal format and converts it
- to old style (driver specific) format.
-
- Note: for the ImageWriter, I'm filling in way more things than theoretically
- I need to. However, since the ImageWriter is one of the oldest print drivers,
- there is much more of a chance that someone assumes something about one or
- more of the fields.
- */
- {
- gxUniversalPrintRecordPtr puPrint; // pointer to universal print record
- THPrint hoPrint = (THPrint) huPrint; // handle to old style print record
- TPPrint poPrint; // pointer to old style print record
- short options; // cached universal options
- short qualityMode; // cached universal quality mode
- short actualCopies; // cached universal copies
-
- // cache pointers for size and speed
- puPrint = *huPrint;
- poPrint = *hoPrint;
-
- // save away fields within the universal record that we'll be stomping over
- // as we convert
- options = puPrint->options;
- qualityMode = puPrint->qualityMode;
- actualCopies = puPrint->actualCopies;
-
- poPrint->iPrVersion = 4; // used to be 3, but this is
- // a new driver. We support versions
- // 3 and 4
- poPrint->prInfo.iDev = 0; // always zero for the ImageWriter
-
- // skip remaining fields in prInfo because they are unchanged
-
- // determine the wDev
- {
- short wDev;
-
- // this is the wDev value for the ImageWriter
- wDev = 0x0100;
-
- if (puPrint->orientation == gxPortraitOrientation)
- wDev |= kPortrait;
- else
- {
- // for landscape, disable draft and force tall adjusted
- if (qualityMode == gxDraftQuality)
- qualityMode = gxFasterQuality;
-
- options |= gxPreciseBitmap;
- }
-
- // user options
- if (options & gxPreciseBitmap)
- wDev |= kTallAdjusted;
- if (options & gxUserFlag0)
- {
- wDev |= k50Percent;
- qualityMode = gxFasterQuality;
- }
-
- if (options & gxBiggerPages)
- wDev |= kNoGaps;
-
- // if the application's resolution isn't 72 - then clearly SetRsl must have been called
- // to change it.
- if (poPrint->prInfo.iVRes != 72)
- {
- wDev |= kSetResCalled;
- qualityMode = gxBestQuality; /* ?? qualityMode == gxBestQuality */
- }
-
- if (qualityMode == gxBestQuality)
- wDev |= kBest;
-
-
- // and finally, save away that short value we worked so hard to determine
- poPrint->prStl.wDev = wDev;
- }
-
- // other fields in prStl remain the same
-
- poPrint->prStl.bPort = 0;
- poPrint->prStl.feed = 1 - (puPrint->feed);
- poPrint->prInfoPT.iDev = (qualityMode == gxBestQuality) ? -768 : 0;
-
- // other fields in prInfoPT remain the same
- {
- Rect rPage = poPrint->prInfoPT.rPage;
-
- // calculate some fields we don't use - in case someone really wants to look at
- // them for some reason
- poPrint->prXInfo.iRowBytes = rPage.right >> 3;
- poPrint->prXInfo.iBandV = 32;
- poPrint->prXInfo.iBandH = poPrint->prXInfo.iRowBytes << 3;
- poPrint->prXInfo.iDevBytes = poPrint->prXInfo.iRowBytes *
- poPrint->prXInfo.iBandV +
- poPrint->prXInfo.iBandH;
- poPrint->prXInfo.iBands = (rPage.bottom+(poPrint->prXInfo.iBandV-1)) / poPrint->prXInfo.iBandV;
- poPrint->prXInfo.bPatScale = (qualityMode == gxBestQuality) ? -2 : 0;
- poPrint->prXInfo.bUlThick = 1;
- poPrint->prXInfo.bUlOffset = 1;
- poPrint->prXInfo.bUlShadow = 1;
- poPrint->prXInfo.scan = (poPrint->prStl.wDev & kPortrait) ? 0 : 2;
- poPrint->prXInfo.bXInfoX = 0;
- }
-
- // other fields in prJob remain the same
- poPrint->prJob.iCopies = actualCopies;
- poPrint->prJob.bJDocLoop = (qualityMode == gxDraftQuality) ? 0 : 1;
-
- // this routine is so studly, there can be no errors
- return(noErr);
-
- } // SD_ConvertPrintRecordFrom
-
-
- //<FF>
- /* ---------------------------------------------------------------------------- */
- OSErr SD_PrintRecordToJob(THPrint hPrint, gxJob theJob)
- /*
- We convert the "tall adjusted" setting into the correct rendering option for
- the job collection.
- */
- {
- OSErr anErr;
- Handle jobQualitySettingsHdl;
-
- anErr = Forward_GXPrintRecordToJob(hPrint, theJob);
- if (anErr == noErr)
- {
- long imagewriterOptions = kSuperRes;
-
- if ((**hPrint).prStl.wDev & kSetResCalled)
- {
- Collection jobCollection = GXGetJobCollection(GXGetJob());
- gxQualityInfo *qualitySettings;
-
-
- // get old info and replace it with final quality
-
-
- jobQualitySettingsHdl = NewHandle(0);
- anErr = MemError();
- nrequire(anErr, FailedNewHandle);
-
- anErr = GetCollectionItemHdl ( jobCollection,
- gxQualityTag,
- gxPrintingTagID,
- jobQualitySettingsHdl );
-
- if (anErr == collectionItemNotFoundErr)
- {
- Str255 bestString, roughString;
- Size count1, count2;
- Ptr p;
-
- GetIndString( bestString, kOldQualityID, kBestString);
- GetIndString( roughString, kOldQualityID, kRoughString);
-
- SetHandleSize(jobQualitySettingsHdl,(sizeof(gxQualityInfo) + bestString[0] + roughString[0] + 2 ));
- anErr = MemError();
- nrequire( anErr, FailedSetHandleSize );
-
- qualitySettings = *((gxQualityInfo **) jobQualitySettingsHdl);
-
- qualitySettings->disableQuality = false;
- qualitySettings->defaultQuality = 1;
- qualitySettings->currentQuality = 1;
- qualitySettings->qualityCount = 2;
-
- count1 = bestString[0]+1;
- p = qualitySettings->qualityNames;
- BlockMove( bestString, p, count1 );
-
- count2 = roughString[0]+1;
- p += count1;
- BlockMove( roughString, p, count2 );
-
- }
- else
- qualitySettings = *((gxQualityInfo **) jobQualitySettingsHdl);
-
- (qualitySettings->currentQuality = qualitySettings->qualityCount-1);
-
- anErr = AddCollectionItemHdl ( jobCollection,
- gxQualityTag,
- gxPrintingTagID,
- jobQualitySettingsHdl );
-
- if (anErr == noErr)
- (void) SetCollectionItemInfo(jobCollection, gxQualityTag, gxPrintingTagID, 0x0000FFFF, gxVolatileOutputDriverCategory);
-
- DisposHandle(jobQualitySettingsHdl);
- }
-
- if ((**hPrint).prStl.wDev & kTallAdjusted)
- imagewriterOptions = 0;
-
- if (anErr == noErr)
- anErr = AddCollectionItem(GXGetJobCollection(theJob),
- DriverCreator,
- 0,
- sizeof(imagewriterOptions),
- &imagewriterOptions);
- }
-
- FailedNewHandle:
- return(anErr);
-
- FailedSetHandleSize:
- DisposHandle(jobQualitySettingsHdl);
- return(anErr);
-
- } // SD_PrintRecordToJob
-
- //<FF>
- /* ---------------------------------------------------------------------------- */
- OSErr SD_PrValidate( THPrint hPrint, // old style print record
- Boolean *wasChanged) // was the print record changed?
- /*
- This call validates the current print record. It's fairly simplistic (as were
- all of the old drivers) - the wDev or versions don't match the current, we call
- PrintDefault. Otherwise, we call UpdatePrintRecord - to allow the driver to sanity
- check any internal fields.
-
- */
- {
- unsigned short wDev; // note: if this were signed, the shift below would fail
- Boolean recordIsInvalid = true;
- OSErr anErr = noErr;
-
- // check the wDev. The upper byte must be equal to our idea of the wDev
-
- wDev = (**hPrint).prStl.wDev;
- wDev >>= 8; // get just the device ID
-
- // If the device id is equal, then check the version number of the print record.
- // Only if that is also equal to the current version, will we return false (valid).
-
- if ( (wDev == 1)
- &&
- (
- ( ((**hPrint).iPrVersion) == 3 ) ||
- ( ((**hPrint).iPrVersion) == 4 )
- )
- )
- recordIsInvalid = false;
-
-
- // If the the print record is not valid, then return the default print record.
- // Otherwise, update the print record, based on the application's calls
- // to PrGeneral.
-
- if (recordIsInvalid)
- PrintDefault(hPrint);
- else
- anErr = UpdatePrintRecord(hPrint);
-
- *wasChanged = recordIsInvalid;
-
- return (anErr);
-
- } // SD_PrValidate
-
-
- // This routine creates a handle for our dialog globals,
- // and stores it in the space we allocated at the end of our
- // jump table.
-
- OSErr CreateAndStoreGlobals(DialogGlobalsHdl *dlogGlobalsHdl)
- {
- OSErr err;
-
- *dlogGlobalsHdl = (DialogGlobalsHdl) TempNewHandle(sizeof(DialogGlobals), &err);
- nrequire(err, TempNewHandle_Failed);
-
- // Clear the data.
-
- (**dlogGlobalsHdl)->inStyleDialog = false;
- (**dlogGlobalsHdl)->originalItemProc = nil;
- (**dlogGlobalsHdl)->optionsDialog = nil;
- (**dlogGlobalsHdl)->flippedPicts = nil;
-
- SetDialogGlobals(*dlogGlobalsHdl);
-
- TempNewHandle_Failed:
- return err;
- }
-
-
- // This routine disposes of our dialog globals.
-
- void DisposeGlobals()
- {
- DialogGlobalsHdl dlogGlobalsHdl;
- char idx;
-
- // Get our dialog globals.
-
- dlogGlobalsHdl = GetDialogGlobals();
- require(dlogGlobalsHdl != nil, NoGlobals);
-
- // If allocated, dispose of the options dialog and release the PICT
- // resources we used there. When done, dispose of the pointer that
- // we used to hold the PicHandles.
-
- if ((*dlogGlobalsHdl)->optionsDialog)
- DisposeDialog((*dlogGlobalsHdl)->optionsDialog);
-
- if ((*dlogGlobalsHdl)->flippedPicts)
- {
- for (idx = 0; idx< 4; idx++)
- if ((*dlogGlobalsHdl)->flippedPicts->pict[idx])
- ReleaseResource((Handle) (*dlogGlobalsHdl)->flippedPicts->pict[idx]);
-
- DisposPtr((Ptr) (*dlogGlobalsHdl)->flippedPicts);
- }
-
- // Finally, dispose of the handle to our globals, and store nil
- // in it's place. This indicates that no valid globals are
- // allocated.
-
- DisposeHandle((Handle) dlogGlobalsHdl);
- SetDialogGlobals(nil);
-
- NoGlobals:;
- }
-
-
- OSErr SD_PrDlgMain(THPrint hPrint, PDlgInitProcPtr initProc, Boolean *userConfirmed)
- {
- OSErr err;
- DialogGlobalsHdl dlogGlobalsHdl;
-
- // Forward the message so that GX handles the Style or Job dialog.
- // On return, retrieve the globals that our init proc created.
-
- err = Forward_GXPrDlgMain(hPrint, initProc, userConfirmed);
-
- dlogGlobalsHdl = GetDialogGlobals();
- require(dlogGlobalsHdl != nil, NoGlobals);
-
-
- // If we just executed the Style dialog, and the user confirmed the
- // dialog, change our format's flipping. Regardless of the dialog,
- // dispose of the globals our initProc allocated.
-
- if ((*dlogGlobalsHdl)->inStyleDialog && *userConfirmed)
- {
- FourPicts *flippedPicts = (*dlogGlobalsHdl)->flippedPicts;
-
- SetFormatFlipping(flippedPicts->curFlipping, GXGetJobFormat(GXGetJob(), 1));
- }
-
- DisposeGlobals();
-
- NoGlobals:
- return err;
- }
-
-
- /* ---------------------------------------------------------------------------- */
- // SD_PrJobInit is an override for GXPrJobInit. Since we need to handle
- // some non-dctl items in this dialog, we override this message and call
- // InitJobDlogData to prepare the dialog.
-
- OSErr SD_PrJobInit(THPrint hPrint, TPPrDlg *pDlg)
- {
- OSErr anErr;
- Boolean disableDraft = false;
- Boolean disableAll = false;
- short wDev = (**hPrint).prStl.wDev;
- short idx;
- Rect box;
- Handle item;
- short type;
-
- anErr = Forward_GXPrJobInit(hPrint, pDlg);
- nrequire(anErr, Forward_Failed);
-
- if (wDev & k50Percent)
- disableAll = true;
-
- if (wDev & kSetResCalled)
- disableAll = true;
-
- if (!(wDev & kPortrait))
- disableDraft = true;
-
- // disable any controls we need to
- for (idx = 6; idx <= 8; ++idx)
- {
- GetDItem((DialogPtr) *pDlg, idx, &type, &item, &box);
-
- if ( (disableAll) || ((disableDraft) && (idx == 8) ) )
- HiliteControl((ControlHandle) item, 255);
- }
-
- InitJobDlogData(*pDlg);
-
- Forward_Failed:
- return anErr;
-
- } // SD_PrJobInit
-
-
-
- // InitJobDlogData is called by SD_PrJobInit to confugure our print
- // dialog at job init time. We need to enforce the following rules
- // using our (non-dctl) quality popup menu control:
- //
- // - 50% disables all items
- // - apps that call SetRsl disable all items
- // - landscape disables draft mode
- //
- // Also, we replace the dialog's item handler with our own, and store
- // it away for later use by HandleJobDlogItems. This way, we can use dctl
- // and non-dctl items in the same dialog.
- //
- // Note that this routine requires cleanup (ie. disposal) of data, and
- // that's why we call DisposeGlobals from SD_PrDlgMain.
-
- OSErr InitJobDlogData(TPPrDlg pDlg)
- {
- OSErr err;
- short wDev, itemType, qualMode;
- THPrint hPrint;
- Handle itemH;
- Rect itemBox;
- Boolean disableDraft, disableAll;
- MenuHandle qualMenu;
- DialogGlobalsHdl dlogGlobalsHdl;
-
- // Create our dialog globals.
-
- err = CreateAndStoreGlobals(&dlogGlobalsHdl);
- nrequire(err, CreateAndStoreGlobals_Failed);
-
-
- // Indicate that we're executing the Job dialog.
- (*dlogGlobalsHdl)->inStyleDialog = false;
-
-
- // Get the print record handle, the driver's wDev, the handle to our
- // quality popup control in the job dialog, and a handle to our
- // quality menu. Note that you should NOT use GetMenu to do this.
- // GetMenu should only be called once per menu.
-
- hPrint = pDlg->hPrintUsr;
- wDev = (*hPrint)->prStl.wDev;
- GetDItem((DialogPtr) pDlg, d_QualPopUp, &itemType, &itemH, &itemBox);
- qualMenu = (MenuHandle) GetResource('MENU', r_QualPopUpMenu);
-
-
- // If we're printing at 50% reduction or PrGeneral's setRsl was used,
- // disable all quality settings. If we're printing in landscape mode,
- // disable draft mode.
-
- disableAll = ((wDev & k50Percent) || (wDev & kSetResCalled))? true: false;
- disableDraft = (!(wDev & kPortrait))? true:false;
-
- HiliteControl((ControlHandle) itemH, (disableAll)? 255:0);
-
- if (disableDraft)
- DisableItem(qualMenu, i_DraftItem);
- else
- EnableItem(qualMenu, i_DraftItem);
-
-
- // Now determine the current quality mode, and set our quality control's
- // value to that.
-
- if (!disableAll)
- {
- if ((*hPrint)->prJob.bJDocLoop == 0)
- qualMode = 3; // draft mode.
- else
- {
- if ((*hPrint)->prStl.wDev & kBest)
- qualMode = 1; // best mode.
- else
- qualMode = 2; // faster mode.
- }
- }
-
- GetDItem((DialogPtr) pDlg, d_QualPopUp, &itemType, &itemH, &itemBox);
- SetCtlValue((ControlHandle) itemH, qualMode);
-
-
- // Finally, save the old item handler proc (which will be used by the dctl items),
- // and store our driver's item proc (for our non-dctl items).
-
- (*dlogGlobalsHdl)->originalItemProc = pDlg->pItemProc;
- pDlg->pItemProc = (PItemProcPtr) HandleJobDlogItems;
-
- CreateAndStoreGlobals_Failed:
- return err;
- }
-
-
- // HandleJobDlogItems is our item handling routine for the job dialog.
- // The only item we handle is the OK button, which simply records
- // our quality pop-up control settings in the print record. All
- // other items are passed to the GX item handler, since they are
- // in our dctl resource. This way, we get the benefits of dctls,
- // but we can still support non-dctl controls.
-
- pascal void HandleJobDlogItems(TPPrDlg pDlg, short itemNo)
- {
- short itemType, qualMode;
- Handle itemH;
- THPrint hPrint;
- Rect itemBox;
- DialogGlobalsHdl dlogGlobalsHdl;
- Ptr *originalItemProc;
-
- // Retrieve our dialog globals, and from those, GX's original
- // itemProc.
-
- dlogGlobalsHdl = GetDialogGlobals();
- require(dlogGlobalsHdl != nil, NoGlobals);
-
- originalItemProc = (*dlogGlobalsHdl)->originalItemProc;
-
-
- // If the ok button was hit, store our quality mode. Regardless of
- // the item which was hit, pass control to the GX dialog item handler
- // routine (which we stored in InitJobDlogData). That way, the GX
- // itemProc can do it's thing for dctl items.
-
- switch (itemNo)
- {
- case ok:
- (pDlg)->fDoIt = (pDlg)->fDone = true;
-
- GetDItem((DialogPtr) pDlg, d_QualPopUp, &itemType, &itemH, &itemBox);
- qualMode = GetCtlValue((ControlHandle) itemH);
-
- hPrint = pDlg->hPrintUsr;
-
- switch (qualMode)
- {
- case 1: // best mode.
- (*hPrint)->prStl.wDev |= kBest;
- (*hPrint)->prJob.bJDocLoop = 1;
- break;
-
- case 2: // faster mode.
- (*hPrint)->prStl.wDev = ((*hPrint)->prStl.wDev >>1) <<1;
- (*hPrint)->prJob.bJDocLoop = 1;
- break;
-
- default: // draft mode.
- (*hPrint)->prStl.wDev = ((*hPrint)->prStl.wDev >>1) <<1;
- (*hPrint)->prJob.bJDocLoop = 0;
- break;
- }
- ((pascal void (*) (TPPrDlg, short)) originalItemProc) (pDlg, itemNo);
- break;
-
- default:
- ((pascal void (*) (TPPrDlg, short)) originalItemProc) (pDlg, itemNo);
- break;
- }
-
- NoGlobals:;
- }
-
-
- // SD_PrStlInit is an override for GXPrStlInit. Since we need to handle
- // some non-dctl items in this dialog, we override this message and call
- // InitStlDlogData to prepare the dialog.
-
- OSErr SD_PrStlInit(THPrint hPrint, TPPrDlg *pDlg)
- {
- OSErr err;
-
- // Forward the message, then initialize our data.
-
- err = Forward_GXPrStlInit(hPrint, pDlg);
- nrequire(err, Forward_Failed);
-
- err = InitStlDlogData(*pDlg);
-
- Forward_Failed:
- return err;
- }
-
-
- // InitStlDlogData is called by SD_PrStlInit to confugure our print
- // dialog at job init time.
- //
- // Also, we replace the dialog's item handler with our own, and store
- // it away for later use by HandleJobDlogItems. This way, we can use dctl
- // and non-dctl items in the same dialog.
- //
- // Note that this routine requires cleanup (ie. disposal) of data, and
- // that's why we call DisposeGlobals from SD_PrDlgMain.
-
- OSErr InitStlDlogData(TPPrDlg pDlg)
- {
- OSErr err = noErr;
- short oldResFile;
- gxFlipPageHorizontalInfo hFlipInfo;
- gxFlipPageVerticalInfo vFlipInfo;
- long itemSize;
- gxFormat pageFormat;
- DialogGlobalsHdl dlogGlobalsHdl;
- FourPicts *flippedPicts;
- DialogPtr optionsDialog;
-
- // Create our dialog globals.
-
- err = CreateAndStoreGlobals(&dlogGlobalsHdl);
- nrequire(err, CreateAndStoreGlobals_Failed);
-
-
- // Indicate that we're executing the Style dialog.
- (*dlogGlobalsHdl)->inStyleDialog = true;
-
-
- // Save the current resource file and use our driver's. Then,
- // get our options dialog and store a pointer to it in our globals.
- // Store a pointer to the options dialog, in our globals. We do
- // this so that the information is available in our item handler proc.
- //
- // Also, store the GX item handler, and replace it with our own. This
- // will enable us to service non-dctl items in HandleStlDlogItems, and
- // still let GX handle the dctls items.
-
- oldResFile = CurResFile();
- UseResFile(GXGetMessageHandlerResFile());
-
- optionsDialog = GetNewDialog(r_OptionsDialog, nil, (WindowPtr) -1);
- (*dlogGlobalsHdl)->optionsDialog = optionsDialog;
- require_action(optionsDialog != nil, GetNewDialog_Failed, err = resNotFound;);
-
- (*dlogGlobalsHdl)->originalItemProc = pDlg->pItemProc;
- pDlg->pItemProc = (PItemProcPtr) HandleStlDlogItems;
-
-
- // Get the job's default format's collection, and from that get the
- // horizontal and vertical flip settings. If we can't find either,
- // interpret that as "don't flip" in the appropriate direction.
-
- pageFormat = GXGetJobFormat(GXGetJob(), 1);
-
- itemSize = sizeof(gxFlipPageHorizontalInfo);
-
- err = GetFmtCollectionItem(&hFlipInfo, &itemSize, gxFlipPageHorizontalTag,
- gxPrintingTagID, pageFormat);
-
- if (err) hFlipInfo.flipHorizontal = false;
-
- itemSize = sizeof(gxFlipPageVerticalInfo);
-
- err = GetFmtCollectionItem(&vFlipInfo, &itemSize, gxFlipPageVerticalTag,
- gxPrintingTagID, pageFormat);
-
- if (err)
- {
- vFlipInfo.flipVertical = false;
- err = noErr;
- }
-
- // Create our global structure to hold handles to the four flip
- // pictures that we draw in the options dialog. Also store this
- // pointer in our dialog globals, so that we can access it from
- // HandleStlDlogItems.
-
- flippedPicts = (FourPicts *) NewPtrSysClear(sizeof(FourPicts));
- (*dlogGlobalsHdl)->flippedPicts = flippedPicts;
-
-
- // Set up the current flipping field in our data structure to reflect
- // the type of flipping that's currently set-- 0 = no flipping,
- // 1 = horizontal flipping, 2 = vertical flipping, 3 = horizontal and
- // vertical flipping. Based on the current flipping, mark the
- // appropriate dialog checkboxes.
-
- flippedPicts->curFlipping = hFlipInfo.flipHorizontal
- + 2 * (char) vFlipInfo.flipVertical;
-
- SetCurFlip(optionsDialog, flippedPicts->curFlipping);
-
-
- // Set up the current flipping field in our data structure to reflect
- // the type of flipping. When done, restore the original resource file
- // and exit.
-
- flippedPicts->pict[0] = (PicHandle) Get1Resource('PICT', p_Normal);
- nrequire((err = ResError()), CouldNotLoadPict);
- flippedPicts->pict[1] = (PicHandle) Get1Resource('PICT', p_HFlip);
- nrequire((err = ResError()), CouldNotLoadPict);
- flippedPicts->pict[2] = (PicHandle) Get1Resource('PICT', p_VFlip);
- nrequire((err = ResError()), CouldNotLoadPict);
- flippedPicts->pict[3] = (PicHandle) Get1Resource('PICT', p_HVFlip);
- err = ResError();
-
- CouldNotLoadPict:
- GetNewDialog_Failed:
- UseResFile(oldResFile);
-
- CreateAndStoreGlobals_Failed:
- return err;
- }
-
-
- // HandleStlDlogItems is our item handling routine for the style dialog.
- // The only item we handle is the "options" button, which brings up
- // the options dialog we've added. All other items are passed to
- // the GX item handler, since they are in our dctl resource. This
- // way, we get the benefits of dctls, but we can still support
- // non-dctl controls.
-
- pascal void HandleStlDlogItems(TPPrDlg pDlg, short itemNo)
- {
-
- // If the "options" button was hit, go handle it. Otherwise, pass
- // control to the GX dialog item handler routine (which we stored in
- // InitStlDlogData).
-
- switch (itemNo)
- {
- case r_OptionsButton:
- DoOptionsDialog();
- break;
-
- default:
- {
- DialogGlobalsHdl dlogGlobalsHdl;
- Ptr *originalItemProc;
-
- dlogGlobalsHdl = GetDialogGlobals();
-
- if (dlogGlobalsHdl != nil) // It better not!!
- {
- originalItemProc = (*dlogGlobalsHdl)->originalItemProc;
- ((pascal void (*) (TPPrDlg, short)) originalItemProc) (pDlg, itemNo);
- }
- }
- }
- }
-
-
- // DoOptionsDialog is our routine to get, display and handle the
- // options dialog (which is accessible from our style dialog).
-
- void DoOptionsDialog()
- {
- DialogPtr optionsDlog;
- GrafPtr oldPort;
- short itemHit;
- char oldSettings;
- DialogGlobalsHdl dlogGlobalsHdl;
-
- // Retrieve the pointer to our dialog, which we stored during
- // InitStlDlogData. Save the old grafport, display the window,
- // select it, and set it as the current grafport.
-
- dlogGlobalsHdl = GetDialogGlobals();
- require(dlogGlobalsHdl != nil, NoGlobals);
- optionsDlog = (*dlogGlobalsHdl)->optionsDialog;
-
- GetPort(&oldPort);
- ShowWindow(optionsDlog);
- SelectWindow(optionsDlog);
- SetPort(optionsDlog);
-
-
- // Save the current flip settings, in case the user cancels after
- // changing them, then go into a ModalDialog loop until the user
- // hits OK or cancel.
-
- oldSettings = GetCurFlip(optionsDlog, d_HFlip, d_VFlip);
-
- do
- {
- ModalDialog(OptionsDlogFilterProc, &itemHit);
- HandleOptionsDlogItems(itemHit);
- GXJobIdle();
- }
- while ((itemHit != ok) && (itemHit != cancel));
-
-
- // Hide the dialog (we don't dispose of it until DisposeStlDlogData,
- // since the user may want to go back to the dialog again). Also,
- // select the old window (the style dialog) and restore that as the
- // current port. If the user cancelled, store the original flip
- // setting back in the job.
-
- HideWindow(optionsDlog);
- SelectWindow(oldPort);
- SetPort(oldPort);
-
- if (itemHit == cancel)
- SetCurFlip(optionsDlog, oldSettings);
-
- NoGlobals:;
- }
-
-
- // OptionsDlogFilterProc is our ModalDialog filter proc for the
- // options dialog. It handles updating our dialog's items.
-
- pascal Boolean OptionsDlogFilterProc(DialogPtr theDialog, EventRecord *theEvent,
- short *itemHit)
- {
- short itemType;
- Handle itemH;
- Rect itemBox;
-
- #pragma unused(itemHit);
-
- // If we're updating, draw the item for the line at the top of
- // the dialog, a picture demonstrating the effect of the current
- // flip settings, and the OK button outline. We still return false
- // because we want the DialogMgr to handle updating the rest of the
- // dialog.
-
- if (theEvent->what == updateEvt)
- {
- GetDItem(theDialog, d_LineItem, &itemType, &itemH, &itemBox);
- MoveTo(itemBox.left, itemBox.top);
- LineTo(itemBox.right, itemBox.top);
- MoveTo(itemBox.left, itemBox.bottom);
- LineTo(itemBox.right, itemBox.bottom);
-
- DrawFlippedPict();
-
- GetDItem(theDialog, ok, &itemType, &itemH, &itemBox);
- PenSize(3, 3);
- InsetRect(&itemBox, -4, -4);
- FrameRoundRect(&itemBox, 16, 16);
- PenSize(1, 1);
- }
-
- return false;
- }
-
-
- // HandleOptionsDlogItems is our ModalDialog item handler for the
- // options dialog. Note that if this dialog had items that could
- // be controlled through a dctl, we wouldn't even need this routine.
- // We could have made the options dialog a "DialogBtn" dctl item,
- // and had a dctl which instructed how to handle the options dialog.
- // We're implementing a totally non-dctl dialog here primarily as a
- // demonstration (note that there is support for handling page
- // flipping via dctl items, so you could handle the options via dctls.
- // But, then we wouldn't be able to use our way-cool camel picture.
- // Cascading dialogs must be totally dctl-driven, or not use dctls
- // at all).
-
- void HandleOptionsDlogItems(short itemNo)
- {
- short itemType;
- Handle itemH;
- Rect itemBox;
- DialogPtr theDialog;
- DialogGlobalsHdl dlogGlobalsHdl;
-
- // Retrieve our dialog globals.
-
- dlogGlobalsHdl = GetDialogGlobals();
- require(dlogGlobalsHdl != nil, NoGlobals);
-
- // Get the options dialog. If the item hit was one of the flipping
- // checkboxes, toggle it's value and redraw the dialog's picture.
-
- theDialog = (DialogPtr) (*dlogGlobalsHdl)->optionsDialog;
-
- switch (itemNo)
- {
- case d_HFlip:
- case d_VFlip:
- GetDItem(theDialog, itemNo, &itemType, &itemH, &itemBox);
- ToggleControl((void **) itemH);
- DrawFlippedPict();
- break;
- }
-
- NoGlobals:;
- }
-
-
- // ToggleControl toggles a control on or off. It's useful for controls
- // like checkboxes or radio buttons, which can only have a value of 0
- // or 1. The function takes a "void **" so that we don't have to
- // typecast the handle returned from GetDItem before calling this routine.
-
- void ToggleControl(void **itemH)
- {
- short ctlVal = GetCtlValue((ControlHandle) itemH);
-
- ctlVal = (ctlVal == 1)? 0: 1;
- SetCtlValue((ControlHandle) itemH, ctlVal);
- }
-
-
- // DrawFlippedPict draws a picture in our options dialog which demonstrates
- // the effect of the flip settings currently selected there.
-
- void DrawFlippedPict()
- {
- DialogPtr theDialog;
- FourPicts *flippedPicts;
- char curFlipping;
- short itemType;
- Handle itemH;
- Rect itemBox;
- DialogGlobalsHdl dlogGlobalsHdl;
-
- // Retrieve our dialog globals.
-
- dlogGlobalsHdl = GetDialogGlobals();
- require(dlogGlobalsHdl != nil, NoGlobals);
-
- // Get our options dialog and, from that, the user item where we'll draw
- // our picture.
-
- theDialog = (*dlogGlobalsHdl)->optionsDialog;
- GetDItem(theDialog, d_FlipPict, &itemType, &itemH, &itemBox);
-
-
- // Get the current flip setting, store it in case it's changed, and then
- // locate and draw the appropriate PICT. Afterwards, draw a frame around
- // the picture.
-
- curFlipping = GetCurFlip(theDialog, d_HFlip, d_VFlip);
- flippedPicts = (*dlogGlobalsHdl)->flippedPicts;
- flippedPicts->curFlipping = curFlipping;
- DrawPicture(flippedPicts->pict[curFlipping], &itemBox);
-
- InsetRect(&itemBox, -1, -1);
- FrameRect(&itemBox);
-
- NoGlobals:;
- }
-
-
- // SetCurFlip checks/unchecks the flip checkboxes in the options
- // dialog, based on the char passed. The passed value is
- // interpreted like so:
- //
- // curFlipping == 0 -- no flipping.
- // curFlipping == 1 -- horizontal flipping.
- // curFlipping == 2 -- vertical flipping.
- // curFlipping == 3 -- horizontal & vertical flipping.
-
- void SetCurFlip(DialogPtr theDialog, char curFlipping)
- {
- short itemType;
- Handle itemH;
- Rect itemBox;
-
- GetDItem(theDialog, d_HFlip, &itemType, &itemH, &itemBox);
- SetCtlValue((ControlHandle) itemH, (curFlipping & 0x01));
- GetDItem(theDialog, d_VFlip, &itemType, &itemH, &itemBox);
- SetCtlValue((ControlHandle) itemH, (curFlipping & 0x02));
- }
-